package com.thwj.project.push;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.thwj.common.utils.StringUtils;
import com.thwj.framework.config.properties.WxSmallProgramProperties;
import com.thwj.project.biz.domain.User;
import com.thwj.project.biz.service.IUserService;
import com.thwj.project.push.domain.WxPushMessage;
import com.thwj.project.push.enums.PushTemplateEnumNew;
import com.thwj.project.push.event.WxMpAdminMessageEvent;
import com.thwj.project.push.event.WxMpMessageBatchEvent;
import com.thwj.project.push.event.WxMpMessageEvent;
import com.thwj.project.push.service.IWxPushMessageService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MpPushMessageService {

    @Autowired
    WxMpService wxMpService;
    @Autowired
    WxSmallProgramProperties wxSmallProgramProperties;
    @Autowired
    IWxPushMessageService pushMessageService;
    @Autowired
    IUserService userService;

    @Async
    @TransactionalEventListener
    public void pushMessageWxMpAdminMessageEvent(WxMpAdminMessageEvent event){
        List<User> userList = userService.list(
                new QueryWrapper<User>().eq("office_user",true).eq("subscribe_mp",true)
        );
        if(CollectionUtils.isEmpty(userList)) {
            return;
        }
        List<WxPushMessage> wxPushMessageList = new ArrayList<>();
        userList.forEach(user ->{
            // 没有关注公众号
            if(StringUtils.isEmpty(user.getMpOpenid())) {
                log.info("该用户未关注公众号，推送失败 event：{}",event);
                wxPushMessageList.add(initWxPushMessage(user.getId(),null,false,"该用户未关注公众号，推送失败"));
                return;
            }
            WxMpTemplateMessage message = new WxMpTemplateMessage();
            message.setTemplateId(event.getPushTemplateEnum().getCode());
            message.setToUser(user.getMpOpenid());
            //标记消息为后台消息
            if (!CollectionUtils.isEmpty(event.getTemplateDataList())) {
                String firstKeyValue = event.getTemplateDataList().get(0).getValue() + "[后台查看]";
                event.getTemplateDataList().get(0).setValue(firstKeyValue);
            }

            if(StringUtils.isNotEmpty(event.getMiniAppPath())) {
                WxMpTemplateMessage.MiniProgram miniProgram= new WxMpTemplateMessage.MiniProgram();
                miniProgram.setAppid(wxSmallProgramProperties.getAppid());
                miniProgram.setPagePath(event.getMiniAppPath());
                message.setMiniProgram(miniProgram);
            }
            message.setData(event.getTemplateDataList());
            try {
                wxMpService.getTemplateMsgService().sendTemplateMsg(message);
                wxPushMessageList.add(initWxPushMessage(user.getId(),message,true,null));
            } catch (WxErrorException e) {
                log.error("微信公众号推送失败：{}", e);
                wxPushMessageList.add(initWxPushMessage(user.getId(),message,false,e.getMessage()));
            }
        });
        if(!CollectionUtils.isEmpty(wxPushMessageList)) {
            pushMessageService.saveBatch(wxPushMessageList);
        }

    }

    @Async
    @TransactionalEventListener
    public void pushMessage(WxMpMessageEvent event){

        User user = userService.getById(event.getUserId());
        if(user == null) {
            return;
        }
        // 没有关注公众号
        if(StringUtils.isEmpty(user.getMpOpenid())) {
            log.info("该用户未关注公众号，推送失败 event：{}",event);
            insertWxPushMessage(event.getUserId(), null,false,"该用户未关注公众号，推送失败");
            return;
        }
        WxMpTemplateMessage message = new WxMpTemplateMessage();
        message.setTemplateId(event.getPushTemplateEnum().getCode());
        if(StringUtils.isNotEmpty(event.getMiniAppPath())) {
            WxMpTemplateMessage.MiniProgram miniProgram= new WxMpTemplateMessage.MiniProgram();
            miniProgram.setAppid(wxSmallProgramProperties.getAppid());
            miniProgram.setPagePath(event.getMiniAppPath());
            message.setMiniProgram(miniProgram);
        }
        message.setToUser(user.getMpOpenid());
        message.setData(event.getTemplateDataList());
        try {
            wxMpService.getTemplateMsgService().sendTemplateMsg(message);
            insertWxPushMessage(event.getUserId(),message,true,null);
        } catch (WxErrorException e) {
            log.error("微信公众号推送失败：{}", e);
            insertWxPushMessage(event.getUserId(),message ,false, e.getMessage());
        }

    }

    @Async
    @TransactionalEventListener
    public void pushBatchMessage(WxMpMessageBatchEvent event){

        List<User> userList = userService.listByIds(event.getUserIdList());

        List<WxPushMessage> wxPushMessageList = new ArrayList<>();
        event.getUserIdList().forEach(userId ->{
            List<User> userListOne = userList.stream().filter(item->item.getId().compareTo(userId) == 0).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(userListOne)) {
                return;
            }
            // 没有关注公众号
            if(StringUtils.isEmpty(userListOne.get(0).getMpOpenid())) {
                log.info("该用户未关注公众号，推送失败 event：{}",event);
                wxPushMessageList.add(initWxPushMessage(userId,null,false,"该用户未关注公众号，推送失败"));
                return;
            }
            WxMpTemplateMessage message = new WxMpTemplateMessage();
            message.setTemplateId(event.getPushTemplateEnum().getCode());

            if(StringUtils.isNotEmpty(event.getMiniAppPath())) {
                WxMpTemplateMessage.MiniProgram miniProgram= new WxMpTemplateMessage.MiniProgram();
                miniProgram.setAppid(wxSmallProgramProperties.getAppid());
                miniProgram.setPagePath(event.getMiniAppPath());
                message.setMiniProgram(miniProgram);
            }
            message.setToUser(userListOne.get(0).getMpOpenid());
            message.setData(event.getTemplateDataList());
            try {
                wxMpService.getTemplateMsgService().sendTemplateMsg(message);
                wxPushMessageList.add(initWxPushMessage(userId,message,true,null));
            } catch (WxErrorException e) {
                log.error("微信公众号推送失败：{}", e);
                wxPushMessageList.add(initWxPushMessage(userId,message,false,e.getMessage()));
            }
        });
        if(!CollectionUtils.isEmpty(wxPushMessageList)) {
            pushMessageService.saveBatch(wxPushMessageList);
        }
    }
    // 记录插入数据
    private void insertWxPushMessage(Long userId, WxMpTemplateMessage message, Boolean pushSuccess,String exceptionMessage){

        WxPushMessage wxPushMessage = new WxPushMessage();
        wxPushMessage.setCreateDate(new Date());
        wxPushMessage.setOpenid(message.getToUser());
        wxPushMessage.setUserId(userId);
        wxPushMessage.setTemplateCode(PushTemplateEnumNew.getEnumByValue(message.getTemplateId()).getCode());
        wxPushMessage.setTemplateName(PushTemplateEnumNew.getEnumByValue(message.getTemplateId()).getName());
        wxPushMessage.setData(JSON.toJSONString(message));
        wxPushMessage.setPushSuccess(pushSuccess);
        wxPushMessage.setExceptionMessage(exceptionMessage);
        pushMessageService.save(wxPushMessage);
    }

    private WxPushMessage initWxPushMessage(Long userId, WxMpTemplateMessage message, Boolean pushSuccess,String exceptionMessage){

        WxPushMessage wxPushMessage = new WxPushMessage();
        wxPushMessage.setCreateDate(new Date());
        wxPushMessage.setOpenid(message.getToUser());
        wxPushMessage.setUserId(userId);
        wxPushMessage.setTemplateCode(PushTemplateEnumNew.getEnumByValue(message.getTemplateId()).getCode());
        wxPushMessage.setTemplateName(PushTemplateEnumNew.getEnumByValue(message.getTemplateId()).getName());
        wxPushMessage.setData(JSON.toJSONString(message));
        wxPushMessage.setPushSuccess(pushSuccess);
        wxPushMessage.setExceptionMessage(exceptionMessage);
        return wxPushMessage;
    }

}
